﻿

using System.Collections.Generic;
using UnityEngine;
using Framework.Common;
using BridgeShips.FSM;
using Framework.FSM;

namespace BridgeShips
{

    public class VehicleOperator
    {

        public string m_vehicleName = string.Empty;
        private Managers managers = null;

        public string VehicleName
        {
            get
            {
                return m_vehicleName;
            }
        }
        public void Init(string strName)
        {
            managers = new Managers();
            m_vehicleName = strName;
        }
        public void PostInit()
        {
            managers.PostInit();
        }
        public void GenEntityManager(VehicleEntity vehicleEntity)
        {
            Init(vehicleEntity.Get().name);
            if (managers != null)
            {
                managers.AddManager<EntityAnimatinControl>();
                managers.AddManager<EntityMovementControl>();
                managers.AddManager<EntityLaserLightControl>();
                managers.AddManager<EntityGlowingControl>();

                managers.Init(vehicleEntity);
                managers.InitDown();
                managers.GetManager<EntityAnimatinControl>();
                managers.GetManager<EntityMovementControl>();
                managers.GetManager<EntityLaserLightControl>();
                managers.GetManager<EntityGlowingControl>();

            }
        }
        public void Update()
        {
            managers.Update(Time.deltaTime, Time.unscaledDeltaTime);
        }
    }

    public class VehicleEntityManager : Singleton<VehicleEntityManager>
    {



        private LinkedList<VehicleOperator> m_VehicleOperator;

        public LinkedList<Vector3> m_list = new LinkedList<Vector3>();

        public enum EntityLinkState
        {
            None, PreLinked, LastLinked, PreLastLinked
        }

        public class EntityLinkInfo
        {
            public bool bLinked;
            public uint PreShipID;
            public uint LastShipID;
            public EntityLinkState ELState;

            public EntityLinkInfo()
            {
                bLinked = false;
                PreShipID = LastShipID = 0;
                ELState = EntityLinkState.None;
            }

            public void FillID(bool location, uint id)
            {
                if (location)
                {
                    PreShipID = id >= PreShipID ? id : PreShipID;
                }
                else
                {
                    LastShipID = id <= LastShipID ? id : LastShipID;
                }
            }

            public void Clear()
            {
                bLinked = false;
                PreShipID = LastShipID = 0;
                ELState = EntityLinkState.None;
            }

            public bool IsValid()
            {
                if (PreShipID == LastShipID && ELState == EntityLinkState.None)
                    return false;
                return true;

            }
        }

        public Dictionary<uint, EntityLinkInfo> m_EntityLinkedInfo = new Dictionary<uint, EntityLinkInfo>();


        public double[] arrX = new double[100];
        public double[] arrY = new double[100];

        public void InitStart()
        {
            if (m_VehicleOperator == null)
                m_VehicleOperator = new LinkedList<VehicleOperator>();

            InitData();
        }

        public void PostInitDown()
        {
            if (m_VehicleOperator == null)
                return;
            LinkedListNode<VehicleOperator> node = m_VehicleOperator.First;
            while (node != null)
            {
                node.Value.PostInit();
                node = node.Next;
            }
        }

        public List<IFsmState> GenFsmState()
        {
            List<IFsmState> listFsm = new List<IFsmState>();
            listFsm.Add(new VHalfWayProbeState());
            listFsm.Add(new VHalfWayPosCorrectState());
            listFsm.Add(new VHalfWayIdleState());
            listFsm.Add(new VHalfWayLinkingState());
            listFsm.Add(new VHalfWayLeaveState());

            return listFsm;
        }

        public void SpawnEntityManager(VehicleEntity vehicleEntity)
        {
            if (m_VehicleOperator == null)
                return;

            GameEntry.Instance.EntityManager.AddEntity(vehicleEntity);
            VehicleOperator vo = new VehicleOperator();
            vo.GenEntityManager(vehicleEntity);
            LinkedListNode<VehicleOperator> node = m_VehicleOperator.First;
            if (node == null)
            {
                m_VehicleOperator.AddFirst(new LinkedListNode<VehicleOperator>(vo));
            }
            else
            {
                m_VehicleOperator.AddBefore(node, vo);
            }
            if (true)
            {
                var fsm = GameEntry.Instance.FsmManager.CreateFsm(vehicleEntity.Get(), vehicleEntity.Get().name, GenFsmState());
                if (fsm != null)
                {
                    var fsdb = GameEntry.Instance.VirtualRManager.GetDataBaseByShipID(vehicleEntity.ID);
                    if (fsdb == null)
                        return;

                    GameEntry.Instance.FsmManager.GetFsm(vehicleEntity.Get().name).ChangeState<VHalfWayProbeState>(fsdb);
                }
            }
            // initalize ship link information
            m_EntityLinkedInfo.Add(vehicleEntity.ID, new EntityLinkInfo());
        }

        public void Update()
        {
            if (m_VehicleOperator == null)
                return;
            LinkedListNode<VehicleOperator> node = m_VehicleOperator.First;
            while (node != null)
            {
                node.Value.Update();
                node = node.Next;
            }
        }

        public EntityLinkInfo GetEntityLinkedInfo(uint shipID)
        {
            if (m_EntityLinkedInfo.ContainsKey(shipID))
            {
                return m_EntityLinkedInfo[shipID];
            }
            return new EntityLinkInfo();
        }

        public void RecordEntityLinkedInfo(uint shipID, EntityLinkInfo ELInfor)
        {
            if (m_EntityLinkedInfo.ContainsKey(shipID))
            {
                m_EntityLinkedInfo[shipID] = ELInfor;
            }
            UpdateEntityLinkedInfo(shipID);
        }

        public void UpdateEntityLinkedInfo(uint shipID)
        {
            var preid = m_EntityLinkedInfo[shipID].PreShipID;
            if (preid > 0)
            {
                if (m_EntityLinkedInfo.ContainsKey(preid) && m_EntityLinkedInfo[preid].bLinked)
                {
                    var prepreId = m_EntityLinkedInfo[preid].PreShipID;

                    if (m_EntityLinkedInfo[preid].PreShipID != m_EntityLinkedInfo[prepreId].LastShipID || m_EntityLinkedInfo[prepreId].bLinked)
                    {
                        m_EntityLinkedInfo[preid].bLinked = false;
                        m_EntityLinkedInfo[preid].LastShipID = 0;
                    }

                }
            }

            var lastid = m_EntityLinkedInfo[shipID].LastShipID;
            if (lastid > 0 && m_EntityLinkedInfo.ContainsKey(preid) && m_EntityLinkedInfo[preid].bLinked)
            {
                var lastlastid = m_EntityLinkedInfo[lastid].LastShipID;

                if (m_EntityLinkedInfo[preid].LastShipID != m_EntityLinkedInfo[lastlastid].PreShipID || m_EntityLinkedInfo[lastlastid].bLinked)
                {
                    m_EntityLinkedInfo[lastid].bLinked = false;
                    m_EntityLinkedInfo[lastid].PreShipID = 0;
                }
            }
        }

        public void RemoveVehicleOperator(string vehicleName)
        {
            if (m_VehicleOperator == null)
                return;
            LinkedListNode<VehicleOperator> node = m_VehicleOperator.First;
            while (node != null)
            {
                if (node.Value.VehicleName == vehicleName)
                    m_VehicleOperator.Remove(node);
                return;
            }
        }

        public void InitData()
        {
            arrX[0] = 117.2822608; arrY[0] = 34.315156;
            arrX[1] = 117.2822607; arrY[1] = 34.315156;
            arrX[2] = 117.2822725; arrY[2] = 34.315156;
            arrX[3] = 117.282228; arrY[3] = 34.315156;
            arrX[4] = 117.2822617; arrY[4] = 34.315169;
            arrX[5] = 117.2822615; arrY[5] = 34.31517917;
            arrX[6] = 117.282261; arrY[6] = 34.31518867;
            arrX[7] = 117.2822618; arrY[7] = 34.31519917;
            arrX[8] = 117.2822623; arrY[8] = 34.31521017;
            arrX[9] = 117.2822623; arrY[9] = 34.31522283;
            arrX[10] = 117.2822635; arrY[10] = 34.31523617;
            arrX[11] = 117.2822648; arrY[11] = 34.31524933;
            arrX[12] = 117.2822655; arrY[12] = 34.31526183;
            arrX[13] = 117.2822657; arrY[13] = 34.31527433;
            arrX[14] = 117.2822657; arrY[14] = 34.31528633;
            arrX[15] = 117.282266; arrY[15] = 34.31529833;
            arrX[16] = 117.2822665; arrY[16] = 34.31531067;
            arrX[17] = 117.2822675; arrY[17] = 34.315321;
            arrX[18] = 117.2822677; arrY[18] = 34.31532367;
            arrX[19] = 117.2822685; arrY[19] = 34.31532367;
            arrX[20] = 117.2822695; arrY[20] = 34.3153235;
            arrX[21] = 117.2822715; arrY[21] = 34.3153235;
            arrX[22] = 117.2822725; arrY[22] = 34.3153235;
            arrX[23] = 117.2822745; arrY[23] = 34.3153235;
            arrX[24] = 117.2822755; arrY[24] = 34.31532367;
            arrX[25] = 117.2822775; arrY[25] = 34.3153235;
            arrX[26] = 117.2822795; arrY[26] = 34.31532367;
            arrX[27] = 117.28228075; arrY[27] = 34.31532367;
            arrX[28] = 117.2822817; arrY[28] = 34.31532367;
            arrX[29] = 117.2822825; arrY[29] = 34.3153235;
            arrX[30] = 117.2822835; arrY[30] = 34.3153235;
            arrX[31] = 117.2822845; arrY[31] = 34.3153235;
            arrX[32] = 117.2822853; arrY[32] = 34.3153235;
            arrX[33] = 117.2822875; arrY[33] = 34.3153235;
            arrX[34] = 117.2822885; arrY[34] = 34.3153235;
            arrX[35] = 117.2822905; arrY[35] = 34.3153235;
            arrX[36] = 117.2822915; arrY[36] = 34.3153235;
            arrX[37] = 117.2822925; arrY[37] = 34.3153235;
            arrX[38] = 117.2822935; arrY[38] = 34.3153235;
            arrX[39] = 117.2822945; arrY[39] = 34.3153235;
            arrX[40] = 117.2822965; arrY[40] = 34.3153235;
            arrX[41] = 117.2822985; arrY[41] = 34.3153235;
            arrX[42] = 117.2822999; arrY[42] = 34.3153235;
            arrX[43] = 117.2823015; arrY[43] = 34.3153235;
            arrX[44] = 117.2823035; arrY[44] = 34.3153235;
            arrX[45] = 117.2823045; arrY[45] = 34.3153235;
            arrX[46] = 117.2823065; arrY[46] = 34.3153235;
            arrX[47] = 117.2823075; arrY[47] = 34.3153235;
            arrX[48] = 117.2823085; arrY[48] = 34.3153235;
            arrX[49] = 117.2823015; arrY[49] = 34.3153235;
            arrX[50] = 117.2823055; arrY[50] = 34.3153235;
            arrX[51] = 117.2823035; arrY[51] = 34.3153235;
            arrX[52] = 117.2823065; arrY[52] = 34.3153235;
            arrX[53] = 117.2823075; arrY[53] = 34.3153235;
            arrX[54] = 117.2823090; arrY[54] = 34.3153235;
            arrX[55] = 117.2823115; arrY[55] = 34.3153235;
            arrX[56] = 117.2823125; arrY[56] = 34.3153235;
            arrX[57] = 117.2823135; arrY[57] = 34.3153235;
            arrX[58] = 117.28231405; arrY[58] = 34.3153235;
            arrX[59] = 117.2823150; arrY[59] = 34.3153235;
            arrX[60] = 117.2823160; arrY[60] = 34.3153235;
            arrX[61] = 117.2823180; arrY[61] = 34.3153235;
            arrX[62] = 117.2823195; arrY[62] = 34.3153235;
            arrX[63] = 117.2823215; arrY[63] = 34.3153235;
            arrX[64] = 117.2824215; arrY[64] = 34.3153235;
            arrX[65] = 117.2823315; arrY[65] = 34.3153235;
            arrX[66] = 117.2823415; arrY[66] = 34.3153235;
            arrX[67] = 117.2823515; arrY[67] = 34.3153235;
            arrX[68] = 117.2823615; arrY[68] = 34.3153235;
            arrX[69] = 117.2823715; arrY[69] = 34.3153235;
            arrX[70] = 117.2823815; arrY[70] = 34.3153235;
            arrX[71] = 117.2823835; arrY[71] = 34.3153235;
            arrX[72] = 117.2823855; arrY[72] = 34.3153235;
            arrX[73] = 117.2823875; arrY[73] = 34.3153235;
            arrX[74] = 117.2823925; arrY[74] = 34.3153235;
            arrX[75] = 117.2823955; arrY[75] = 34.3153235;
            arrX[76] = 117.2823975; arrY[76] = 34.3153235;
            arrX[77] = 117.2823995; arrY[77] = 34.3153235;
            arrX[78] = 117.2824015; arrY[78] = 34.3153235;
            arrX[79] = 117.2824035; arrY[79] = 34.3153235;
            arrX[80] = 117.2824055; arrY[80] = 34.3153235;
            arrX[81] = 117.2824015; arrY[81] = 34.3153235;
            arrX[82] = 117.2824065; arrY[82] = 34.3153235;
            arrX[83] = 117.2824075; arrY[83] = 34.3153235;
            arrX[84] = 117.2824015; arrY[84] = 34.3153235;
            arrX[85] = 117.2824095; arrY[85] = 34.3153235;
            arrX[86] = 117.2824115; arrY[86] = 34.3153235;
            arrX[87] = 117.2824135; arrY[87] = 34.3153235;
            arrX[88] = 117.2824145; arrY[88] = 34.3153235;
            arrX[89] = 117.2824215; arrY[89] = 34.3153235;
            arrX[90] = 117.2824135; arrY[90] = 34.3153235;
            arrX[91] = 117.2824415; arrY[91] = 34.3153235;
            arrX[92] = 117.2824215; arrY[92] = 34.3153235;
            arrX[93] = 117.2824315; arrY[93] = 34.3153235;
            arrX[94] = 117.2824415; arrY[94] = 34.3153235;
            arrX[95] = 117.2824515; arrY[95] = 34.3153235;
            arrX[96] = 117.2824615; arrY[96] = 34.3153235;
            arrX[97] = 117.2824715; arrY[97] = 34.3153235;
            arrX[98] = 117.2824815; arrY[98] = 34.3153235;
            arrX[99] = 117.2824915; arrY[99] = 34.3153235;

            Vector3 value = Vector3.zero;
            m_list.AddFirst(value);
            for (int i = 0; i < 100; i++)
            {
                value.x = (float)arrX[i];
                value.y = 0.0f;
                value.z = (float)arrY[i];

                m_list.AddLast(value);
            }
        }

        public double GetArrX(int index)
        {
            return arrX[index];
        }
        public double GetArrY(int index)
        {
            return arrY[index];
        }

    }
}